import json

import requests
from uuid import UUID, uuid4
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from bisheng.utils.logger import logger
from bisheng.api.jsj_api.model.metro_fault import Equipment, EquipmentDao
from bisheng.api.jsj_api.model.maintenance_rule import MaintenanceRuleDao, MaintenanceRule

from .config_service import ConfigService


class EquipmentService:

    @staticmethod
    def bulk_create(json_data: str) -> bool:
        try:
            data_list = json.loads(json_data)
            if not isinstance(data_list, list):
                raise ValueError("Input JSON should be a list of objects")

            equipments = []
            for item in data_list:
                equipment_dict = {k: v for k, v in item.items() if k not in ['create_time', 'update_time']}
                equipment_dict.pop('id', uuid4)
                equipment = Equipment(**equipment_dict)
                equipments.append(equipment)

            EquipmentDao.bulk_insert(equipments)
        except json.JSONDecodeError as e:
            logger.error(f"JSON parse error: {str(e)}")
            return False
        except Exception as e:
            logger.error(f"Bulk insert failed: {str(e)}")
            return False

    @staticmethod
    def delete_all() -> bool:
        try:
            EquipmentDao.delete_all()
            return True
        except Exception as e:
            print(f"删除所有设备失败: {str(e)}")
            return False

    @staticmethod
    def get_by_sfcode(sfcode: str):
        try:
            return EquipmentDao.get_by_sfcode(sfcode)
        except Exception as e:
            print(f"查询设备失败: {str(e)}")
            return None

    async def sync_equipments(self, page_size: int = 20, page_num: int = 1):
        try:

            url = ConfigService.get_config_by_key("sync_equipment_info_url").value
            # url = "https://ip:port/classifly/eqInfotable/publicList"
            params = {
                "pageSize": page_size,
                "pageNum": page_num
            }
            response = requests.get(url, params=params)
            print(response.text)
            if response.status_code == 200:
                data = response.json()
                if data["code"] == 200:
                    total = data["total"]
                    rows = data["rows"]
                    # 批量添加到数据库
                    self.bulk_create(json.dumps(rows))
                    if total > page_size * page_num:
                        await self.sync_equipments(page_size, page_num + 1)
                else:
                    print(f"同步设备失败: {data['msg']}")

        except Exception as e:
            print(f"同步设备失败: {str(e)}")


class MaintenanceRuleService:
    @staticmethod
    def get_by_equipment_id(equipment_id: str):
        return MaintenanceRuleDao.get_by_equipment_id(equipment_id)

    @staticmethod
    def delete_all() -> bool:
        try:
            MaintenanceRuleDao.delete_all()
            return True
        except Exception as e:
            print(f"删除所有设备失败: {str(e)}")
            return False

    async def sync_maintenance_rule(self, page_size: int = 20, page_num: int = 1):
        try:
            url = ConfigService.get_config_by_key("sync_maintenance_rule_url").value
            print("url",url)
            params = {
                "pageSize": page_size,
                "pageNum": page_num
            }
            response = requests.get(url, params=params)
            print("response",response.text)
            if response.status_code == 200:
                data = response.json()
                if data["code"] == 200:
                    total = data["total"]
                    rows = data["rows"]
                    # 批量添加到数据库

                    self.create_maintenance_rule(json.dumps(rows))

                    if total > page_size * page_num:
                        await self.sync_maintenance_rule(page_size, page_num + 1)
                else:
                    print(f"同步策略失败: {data['msg']}")

        except Exception as e:
            print(f"同步策略失败: {str(e)}")

    @staticmethod
    def create_maintenance_rule(json_data: str):
        data_list = json.loads(json_data)
        if not isinstance(data_list, list):
            raise ValueError("Input JSON should be a list of objects")

        maintenance_rules = []
        for item in data_list:
            maintenance_rule = MaintenanceRule()
            maintenance_rule.strategyName = item.get('strategyName','')
            maintenance_rule.strategyNumber = item.get('strategyNumber','')
            maintenance_rule.strategyDescription = item.get('strategyDescription','')
            rules = item.get('rules', [])
            if rules and isinstance(rules, list) and len(rules) > 0:
                rule = rules[0]
                if isinstance(rule, dict):
                    maintenance_rule.maintenance_cycle_unit = str(rule.get('cycleUnit', ''))
                    try:
                        maintenance_rule.maintenance_cycle_threshold = int(rule.get('threshold', 0))
                    except ValueError:
                        print(f"周期值异常: {rule.get('threshold')}")
                        maintenance_rule.maintenance_cycle_threshold = 0
                else:
                    print("rule 格式异常")
            else:
                print("rules 为空")

            maintenance_standard = []
            operations = item.get('operations', [])
            for operation in operations:
                jobdetailsList = operation.get('standardJobdetailsList', [])
                for jobdetail in jobdetailsList:
                    technical_standard = jobdetail.get('technicalStandard', '')
                    if technical_standard:
                        maintenance_standard.append(technical_standard)

            maintenance_rule.maintenance_standard = ';'.join(maintenance_standard)

            devices = item.get('devices', [])
            for device in devices:
                maintenance_rule.equipment_id = device.get('sfcode', '')
                maintenance_rule.equipment_name = device.get('sfname', '')
                maintenance_rules.append(maintenance_rule)

        MaintenanceRuleDao.create_maintenance_rule(maintenance_rules)
        return maintenance_rules

    @staticmethod
    def get_past_date(start_date: datetime, cycle_unit: str, threshold: int) -> datetime:
        """
        计算从给定日期往前推指定时间单位和数量后的日期。

        :param start_date: 起始日期
        :param cycle_unit: 周期单位，可以是 '年', '月', '周', 或 '日'
        :param threshold: 周期的数值
        :return: 计算得到的过去日期
        """
        cycle_unit = cycle_unit.strip().lower()
        threshold = int(threshold)
        if cycle_unit == 'day':
            return start_date - timedelta(days=threshold)
        elif cycle_unit == 'week':
            return start_date - timedelta(weeks=threshold)
        elif cycle_unit == 'month':
            return start_date - relativedelta(months=threshold)
        elif cycle_unit == 'year':
            return start_date - relativedelta(years=threshold)
        else:
            raise ValueError(f"不支持的周期单位: {cycle_unit}")

    def get_start_time_by_maintenance_rule(self, maintenance_rule: MaintenanceRule,start_date: datetime) -> datetime:
        if maintenance_rule is None:
            return start_date
        try:
            return self.get_past_date(start_date, maintenance_rule.maintenance_cycle_unit, maintenance_rule.maintenance_cycle_threshold)
        except Exception as e:
            print(f"获取开始时间失败: {str(e)}")